<?php
/**
 * Collector.php
 *
 * 采集器文件，定义采集器
 *
 * PHP Version 5.6
 *
 * @category PHP
 * @package  Collector
 * @author   ctwj <908504609@qq.com>
 * @license  MIT https://mit-license.org/
 * @link     MIT https://mit-license.org/
 * @date     2018-05-13 22:56:47
 * @modifyby ctwj
 */

namespace Telegram;

use Telegram\Collector\CollectorFactory;
use Telegram\Data\ResourceModel;
use Telegram\Data\MessageModel;
use Telegram\Data\BodyModel;
use Telegram\TPLogger;
use Telegram\Object\Resource;
use Telegram\Object\Message;

//use Telegram\Events\MessageEvent;

/**
 * Collector class
 *
 * 采集器类，暴露采集器接口
 *
 * @category PHP
 * @package  Collector
 * @author   ctwj <908504609@qq.com>
 * @license  MIT https://mit-license.org/
 * @link     MIT https://mit-license.org/
 */
class Collector
{

    /**
     * 采集器实例容器
     *
     * @var [array Telegram\Collector\BaseCollect]
     */
    public $collector;

    /**
     * 运行所有采集器
     *
     * @return void
     */
    public function run()
    {
        \getContainer()['logger']->info('start collector');
        $resources = $this->getResources();
        if (!$resources || !is_array($resources) || empty($resources)) {
            \getContainer()['logger']->info('No actived collector');
            exit(1);
        }

        foreach ($resources as $resource) {
            // 检测上次采集时间
            if (!$this->isNeedCollector($resource)) {
                \getContainer()['logger']->info('Don\'t need collect now!', ['resource' => $resource->name]);
                continue;
            }

            // 获取采集器实例
            $type = $resource->type;
            $worker = $this->getInstance($type);
            $worker->loadconfig($resource);

            // 采集数据
            $messages = $worker->collect();
            if (empty($messages)) {
                $resource->last_time = getTime()->format('Y-m-d H:i:s');
                \getService('resourceModel')->updateResource($resource);
                \getContainer()['logger']->info('No Message Found', ['resource' => $resource->name]);
                continue;
            }

            /* collector.after.collect 消息触发
            foreach ($messages as $message) {
                \getService('plugindispatcher')->dispatch(
                    'collector.after.collect',
                    new \Telegram\Events\MessageEvent($message)
                );
            }*/
            
            // 保存数据处理
            $number = $this->saveMessage($messages, $resource);
        }
        \getContainer()['logger']->info('finish collector');
    }

    /**
     * 获取具体类型的采集器实例
     *
     * @param [string] $type 采集器类型
     *
     * @return void
     */
    public function getInstance($type)
    {
        if (isset($this->collector[$type])) {
            return $this->collector[$type];
        }
        $this->collector[$type] = CollectorFactory::getInstance($type);
        return $this->collector[$type];
    }

    /**
     * 获取所有采集器
     *
     * @return array
     */
    public function getResources()
    {
        $list = getContainer()['resourceModel']->getAllActiveResource();
        if (count($list) === 0) {
            return [];
        }
        return array_map(
            function ($item) {
                return new \Telegram\Object\Resource($item);
            },
            $list
        );
    }

    /**
     * 判断是否需要再次采集
     *
     * @param [\Telegram\Object\Resource] $resource 上次采集时间
     *
     * @return boolean
     */
    public function isNeedCollector($resource)
    {
        if (is_null($resource->last_time)) {
            return true;
        }
        if (is_null($resource->frequency) || !is_numeric($resource->frequency)) {
            getService('logger')->info('Collector Need Set Frequency', ['name' => $resource->name]);
            return false;
        }
        $now = getTime();
        $las = getTime($resource->last_time);
        if ($now->getTimestamp() - $las->getTimestamp() > intval($resource->frequency) * 60) {
            return true;
        }
        return false;
    }

    /**
     * 保存数据
     *
     * @param [array of Telegram\Object\Message] $messages Message列表
     * @param [Telegram\Object\Resource]         $resource 资源对象
     *
     * @return integer 成功保存数量
     */
    public function saveMessage($messages, $resource)
    {
        $hashs = array_keys($messages);

        $messageModel = \getService('messageModel');
        $no_exists_hashs = $messageModel->getNoExistsHashs($hashs);

        $insert_ids = [];
        foreach ($no_exists_hashs as $hash) {
            $messages[$hash]->resource_id = $resource->id;
            $id = $messageModel->addMessage($messages[$hash]);
            if (!$id) {
                \getService('logger')->error('Write Message Fail', $messages[$hashs]);
            } else {
                $insert_ids[] = $id;
            }
        }
        if (count($insert_ids)) {
            $resource->message_count += count($insert_ids);
            \getService('logger')->info('Add New Messages', ['reosurce' => $resource->name,'number' => count($insert_ids), 'ids' => $insert_ids]);
        }
        $resource->last_time = getTime()->format('Y-m-d H:i:s');
        \getService('resourceModel')->updateResource($resource);
    }
}
